package com.ly.heart.service.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.erp.CommonUtil;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.heart.domain.KingFinancePayDetailEntity;
import com.ly.heart.domain.KingFinanceReceiptDetailEntity;
import com.ly.heart.domain.KingFinanceReceiptEntity;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.invoice.ReceiptBo;
import com.ly.heart.domain.king.invoice.ReceiptDetail;
import com.ly.heart.domain.request.KingBaseSingleRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseError;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.service.IKingFinancePayDetailService;
import com.ly.heart.service.IKingFinanceReceiptDetailService;
import com.ly.heart.service.IKingFinanceReceiptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Wuzh
 * @Description:
 * @Date Created in 16:19 2024-07-21
 * @return
 */
@Component
@Slf4j
public class ReceiptPushService {


    @Resource
    private IKingFinanceReceiptService iKingFinanceReceiptService;
    @Resource
    private IKingFinanceReceiptDetailService iKingFinanceReceiptDetailService;

    public void push ( KingFinanceReceiptEntity kingFinanceReceiptEntity ) {
        K3CloudApi client = new K3CloudApi ();
        log.info ( "收款单调用金蝶下推->{}", kingFinanceReceiptEntity );
        KingFinanceReceiptEntity receiptEntity = iKingFinanceReceiptService.querySingleById ( kingFinanceReceiptEntity.getId () );
        if ( ObjectUtils.isEmpty ( receiptEntity ) ) {
            throw new CustomException ( "收款单对象为空" );
        }
        ReceiptBo receiptBo = assembleReceipt ( receiptEntity );
        try {
            save ( receiptBo, client );
            submit ( receiptBo, client );
            audit ( receiptBo, client );
            updateSendSuccess ( kingFinanceReceiptEntity.getId () );
        } catch ( Exception e ) {
            e.printStackTrace ();
            throw new CustomException ( "推送失败，请检查后重试！" );
        }
    }

    private void save ( ReceiptBo bo, K3CloudApi client ) throws Exception {
        KingBaseSingleRequest singleRequest = new KingBaseSingleRequest ();
        singleRequest.setModel ( bo );
        String s = JSONObject.toJSONString ( singleRequest );
        log.info ( "收款单转JSON->{}", s );
        String resultJson = client.save ( KingConstUtil.AR_RECEIVEBILL, s );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "收款单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 推送成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "收款单-推送失败：【" + sb + "】" );
        }
    }

    private void submit ( ReceiptBo bo, K3CloudApi client ) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFBillNo () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.submit ( KingConstUtil.AR_RECEIVEBILL, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "收款单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 提交成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "收款单提交失败：【" + sb + "】" );
        }
    }

    private void audit ( ReceiptBo bo, K3CloudApi client ) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFBillNo () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.audit ( KingConstUtil.AR_RECEIVEBILL, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "收款单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 审核成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "收款单审核失败：【" + sb + "】" );
        }
    }

    /**
     * 修改收
     *
     * @param id
     */
    private void updateSendSuccess ( String id ) {
        KingFinanceReceiptEntity receiptEntity = new KingFinanceReceiptEntity ();
        receiptEntity.setId ( id );
        receiptEntity.setIsSend ( KingConstUtil.KING_DATA_IS_SEND_YES );
        boolean b = iKingFinanceReceiptService.updateById ( receiptEntity );
        if ( ! b ) {
            throw new CustomException ( "修改推送金蝶状态失败！" );
        }
    }

    private ReceiptBo assembleReceipt ( KingFinanceReceiptEntity receiptEntity ) {
        ReceiptBo bo = new ReceiptBo ();
        //1.基础
        bo.setFBillNo ( receiptEntity.getDocNo () );
        //单据类型
        BaseChildBo docType = new BaseChildBo ().setFNumber ( receiptEntity.getDocTypeCode () );
        bo.setFBillTypeID ( docType );
        //付款单位类型
        bo.setFPAYUNITTYPE ( receiptEntity.getPayDeptType () );
        //收款组织
        BaseChildBo receiptOrg = new BaseChildBo ().setFNumber ( receiptEntity.getReceiptDeptCode () );
        bo.setFPAYORGID ( receiptOrg ).setFSETTLEORGID ( receiptOrg ).setFSALEORGID ( receiptOrg );
        //付款单位
        BaseChildBo payDept = new BaseChildBo ().setFNumber ( receiptEntity.getPayDeptCode () );
        bo.setFPAYUNIT ( payDept );
        //币别
        BaseChildBo currency = new BaseChildBo ().setFNumber ( receiptEntity.getKingBaseCurrencyCode () );
        bo.setFSETTLECUR ( currency );
        //业务日期
        bo.setFDATE ( CommonUtil.getDateStrFormat ( receiptEntity.getBusinessTime (), "yyyy-MM-dd HH:mm:ss" ) );
        //往来单位类型
        bo.setFCONTACTUNITTYPE ( receiptEntity.getTransactionCompanyType () );
        //销售部门
        BaseChildBo saleDept = new BaseChildBo ().setFNumber ( receiptEntity.getSaleDeptCode () );
        bo.setFSALEDEPTID ( saleDept );
        //往来单位
        BaseChildBo transaction = new BaseChildBo ().setFNumber ( receiptEntity.getTracDeptCode () );
        bo.setFCONTACTUNIT ( transaction );
        //销售员
        BaseChildBo saleUser = new BaseChildBo ().setFNumber ( receiptEntity.getSaleUserCode () );
        bo.setFSALEERID ( saleUser );

        //组装收款单明细
        List<ReceiptDetail> receiptDetails = assembleReceiptDetail ( receiptEntity.getId () );
        bo.setFRECEIVEBILLENTRY ( receiptDetails );

        return bo;
    }

    /**
     * 组装收款单明细
     *
     * @param receiptId
     * @return
     */
    private List<ReceiptDetail> assembleReceiptDetail ( String receiptId ) {
        List<KingFinanceReceiptDetailEntity> list = iKingFinanceReceiptDetailService.list ( new LambdaQueryWrapper<KingFinanceReceiptDetailEntity> ().eq ( KingFinanceReceiptDetailEntity :: getRelationId, receiptId ) );
        List<ReceiptDetail> receiptDetails = new ArrayList<> ();
        //组装明细
        list.forEach ( receiptDetail -> {
            ReceiptDetail detail = new ReceiptDetail ();
            //结算方式
            BaseChildBo settleType = new BaseChildBo ().setFNumber ( receiptDetail.getKingSettlementTypeCode () );
            detail.setFSETTLETYPEID ( settleType );
            //付款用途
            BaseChildBo payPurpose = new BaseChildBo ().setFNumber ( receiptDetail.getReceiptPurposeCode () );
            detail.setFPURPOSEID ( payPurpose );
            //预收项目类型
            detail.setFRECEIVEITEMTYPE ( receiptDetail.getPrepaidItemType () );
            //应收金额
            detail.setFRECTOTALAMOUNTFOR ( receiptDetail.getCopeMoney () );
            //现金折扣
            detail.setFSETTLEDISTAMOUNTFOR ( receiptDetail.getCashDiscount () );
            //手续费
            detail.setFHANDLINGCHARGEFOR ( receiptDetail.getHandlingFees () );
            //长短款
            detail.setFOVERUNDERAMOUNTFOR ( receiptDetail.getLongShortPay () );
            //我方银行账号
            BaseChildBo account = new BaseChildBo ().setFNumber ( receiptDetail.getBankNumber () );
            detail.setFACCOUNTID ( account );

            //备注
            detail.setFCOMMENT ( receiptDetail.getRemarks () );
            //费用项目
            BaseChildBo cost = new BaseChildBo ().setFNumber ( receiptDetail.getFeeCode () );
            detail.setFCOSTID ( cost );
            //费用承担部门
            BaseChildBo expenseDept = new BaseChildBo ().setFNumber ( receiptDetail.getFeeBearDeptCode () );
            detail.setFCOSTDEPARTMENTID ( expenseDept );
            //物料编码
            BaseChildBo materialCode = new BaseChildBo ().setFNumber ( receiptDetail.getMaterialCode () );
            detail.setFMATERIALID ( materialCode );

            //含税单价
            detail.setFPrice ( receiptDetail.getTaxPrice () );
            //销售订单号
            detail.setFSALEORDERNO ( receiptDetail.getSaleOrderCode () );
            //预估税率
            //detail.setFENTRYTAXRATE ( receiptDetail.getExpectTaxRate () );
            //税额
            detail.setFTAXAMOUNTFOR ( receiptDetail.getTaxRate () );
            //应收金额不含税
            //detail.setFRECNOTAXAMOUNTFOR ( receiptDetail.getNoTaxAmount () );
            receiptDetails.add ( detail );
        } );
        return receiptDetails;
    }
}
